package net;

import java.io.*;
import java.util.ArrayList;
import java.net.ServerSocket;
import java.net.Socket;

class pos implements Serializable{
    public double x;
    public double y;

    pos(double x,double y) {
        this.x=x;
        this.y=y;
    }

    public double dist(pos p) {
        double f1=this.x-p.x;
        f1=f1*f1;
        double f2=this.y-p.y;
        f2=f2*f2;
        return Math.sqrt(f1+f2);
    }

    public String toString() {
        return "("+Double.toString(x)+","+Double.toString(y)+")";
    }
}

abstract class GeometricObject implements Serializable {
    public abstract double getC();
    public abstract double getS();
}

class Rectangle extends GeometricObject implements Serializable {
    private double dx;
    private double dy;

    private pos p1;
    private pos p2;

    public Rectangle(pos p1, pos p2) {
        this.p1=p1;
        this.p2=p2;
        this.dx=p2.x-p1.x;
        this.dy=p2.y-p1.y;
    }

    public double getC() {
        return dx*2+dy*2;
    }

    public double getS() {
        return dx*dy;
    }

    public String toString() {
        return "Rectangle: "+Double.toString(dx)+","+Double.toString(dy);
    }
}
class Circle extends GeometricObject implements Serializable{
    public pos p;
    public double r;
    public Circle(pos p, double r) {
        this.p=p;
        this.r=r;
    }

    public double getS() {
        return Math.PI*r*r;
    }

    public double getC() {
        return 2*Math.PI*r;
    }

    public String toString() {
        return "Circle: "+p.toString()+","+Double.toString(r);
    }
}

class Triangle extends GeometricObject implements Serializable{
    private double a;
    private double b;
    private double c;

    private pos p1;
    private pos p2;
    private pos p3;

    public Triangle(pos p1, pos p2, pos p3) {
        this.p1=p1;
        this.p2=p2;
        this.p3=p3;
        this.a=p1.dist(p2);
        this.b=p2.dist(p3);
        this.c=p1.dist(p3);
    }

    public double getC() {
        return a+b+c;
    }

    public double getS() {
        double p=a+b+c/2;
        return Math.sqrt(p*(p-a)*(p-b)*(p-c));
    }

    public String toString() {
        return "Triangle: "+Double.toString(a)+","+Double.toString(b)+","+Double.toString(c);
    }
}

class Manager {
    public ArrayList<Circle> circlelist=new ArrayList<Circle>();
    public ArrayList<Rectangle> reclist=new ArrayList<Rectangle>();
    public ArrayList<Triangle> trianglelist=new ArrayList<Triangle>();
}

class Inseter extends Thread {
    private ArrayList<GeometricObject> list;
    private Manager manager;

    public Inseter(ArrayList<GeometricObject> list, Manager manager) {
        this.list=list;
        this.manager=manager;
    }

    public boolean dealObject(Object o) {
            if(obj instanceof GeometricObject) {
            	GeometricObject str = (GeometricObject) obj;
            	System.out.println("readObject");
            	synchronized (list) {
            		list.add(str);
            	}
            }
            else {
				String str=(String) obj;
				if(str=="END")
					return true;
				else
				{
					System.out.println("查");
					String result="圆形数量s:"+String.valueOf(manager.circlelist.size())+" "+"矩形数量:"+String.valueOf(manager.reclist.size())+" "
									   +"三角形数量:"+ String.valueOf(manager.trianglelist.size())+"\n";
					ObjectOutputStream sp=new ObjectOutputStream(s.getOutputStream());
					sp.writeObject(result);
					sp.flush();
				}
            }
            return false;
    }

    private void realRun()  throws IOException {
    	ServerSocket ss;
        try {
            ss = new ServerSocket(1010);
        }
        catch (IOException e) {
            System.out.println("no!!!");
            return;
        }
        //监听客户端的套接字,并且返回客户端的套接字
        while(true) {
            System.out.println("ready");
            Socket s = ss.accept();  //阻塞式方法
            System.out.println(" 存");
            InputStream is = s.getInputStream();
            ObjectInputStream sb=new ObjectInputStream(is);
            while(true) {
            	Object obj=sb.readObject();
                if(dealObject(obj))
                    break;
            }
            s.close();
        }
    }

    public void run()  {
        try {
            this.realRun();
        }
        catch(IOException e) {}
    }
}

class Disptcher extends Thread{
    private ArrayList<GeometricObject> list;
    private Manager manager;

    public Disptcher(ArrayList<GeometricObject> list, Manager manager) {
        this.list=list;
        this.manager=manager;
    }

    private void realRun() {
        while(true) {
            synchronized (list) {
                if (!list.isEmpty()) {
                    System.out.println("分类");
                    var n = list.get(0);
                    list.remove(0);
                    if (n.getClass().equals(Triangle.class))
                        manager.trianglelist.add((Triangle) n);
                    else if (n.getClass().equals(Circle.class))
                        manager.circlelist.add((Circle) n);
                    else if (n.getClass().equals(Rectangle.class))
                        manager.reclist.add((Rectangle) n);
                    else
                        System.out.println("....");
                }
            }
            try {
                Thread.sleep(100);
            }
            catch (InterruptedException e) {}
        }
    }

    public void run() {
        this.realRun();
    }
}


public class server {
    public static void main(String[] args) {
        var list=new ArrayList<GeometricObject>();
        var manager=new Manager();
        var t1=new Inseter(list,manager);
        var t2=new Disptcher(list,manager);
        t1.start();
        t2.start();
    }
}

